//========================================================================================
/*
 *  AMPWtchDocResponder.cpp
 *  AMPlugin
 *
 *  Created by Toan on 7/6/12.
 *  Copyright 2012 __MyCompanyName__. All rights reserved.
 *
 */ 
//========================================================================================

#include "VCPlugInHeaders.h"

// Interface includes:
#include "IClassIDData.h"
#include "isignalmgr.h"
#include "IDocumentSignalData.h"
#include "IObserver.h"
#include "IPMStream.h"

// General  includes:
#include "CResponder.h"
#include "Trace.h"
#include "IDFile.h"
//#include "StreamUtil.h"
//#include "FileUtils.h"

// Project includes:
#include "AMPID.h"
//#include "ILnkWtchCache.h"
#include "AMGlobal.h"
#include "AMPLogDataRecord.h"
#include "HTTPRequestHelper.h"
#include "AMPCAlert.h"
#include "AMPDocument.h"
#include <iostream>
using namespace std;
/** Attaches and detaches LnkWtchCacheManager as documents are
	created, opened and closed. On close write each entry in
	the cache to this plug-in's log. The log file is created 
	in the defaults folder for the application. 
	For example, for InDesign CS3 the log file can be found
	at the locations below:
	<pre>
	On Windows:
	"C:\Documents and Settings\<user>\Application Data\Adobe\InDesign\Version 5.0\LinkWatcher.txt"

	On Macintosh:
	"/Users/<user>/Library/Preferences/Adobe InDesign/Version 5.0/LinkWatcher.txt"
	</pre>

	@see LnkWtchCacheManager
	@see ILnkWtchCache
	@ingroup linkwatcher
*/
bool		 DocWatchResponseCode = TRUE;

class LnkWtchDocResponder : public CResponder
{
public:
	/** Constructor.
	@param boss object this object is aggregated on.
	*/
	LnkWtchDocResponder(IPMUnknown* boss);

	/** Destructor.
	*/
	virtual ~LnkWtchDocResponder() {}

	/** Attaches LnkWtchCacheManager when documents are created
		or opened, detaches it on close.
		@param signalMgr provides information about the signal.
	*/
	virtual void Respond(ISignalMgr* signalMgr);

private:
	/** Opens a log in the application defaults folder and writes
		each entry in ILnkWtchCache to the log.
		@param documentUIDRef document containing cache to be traced in the log.
	*/
	void LogCacheContent(const UIDRef& documentUIDRef);

	/**	Writes a line to this plug-in's log file.
		@param stream for log output
		@param line to be written out to the log
	*/
	void WriteLine(IPMStream* stream, const std::string& line);
	
	void AfterOpenDocSignalResponder(UIDRef doc);
	
	void BeforeCloseDocSignalResponder(UIDRef doc);
	
	void AfterCloseDocSignalResponder(UIDRef doc);
	
	void BeforeSaveDocSignalResponder(UIDRef doc);
	
	void BeforeSaveAsDocSignalResponder(UIDRef doc);
	
	void AfterSaveAsDocSignalResponder(UIDRef doc);
};

/* Makes the implementation available to the application.
*/
CREATE_PMINTERFACE(LnkWtchDocResponder, kLnkWtchDocResponderImpl)


LnkWtchDocResponder::LnkWtchDocResponder(IPMUnknown* boss) :
CResponder(boss)
{
}

/********************************************************************************************************************
 *****Function: Respond
 *****Creator:  Toan Nguyen
 *****IN: const PMString& parentPath
 *****out: 
 *****Objective: 
 ********************************************************************************************************************/
void LnkWtchDocResponder::Respond(ISignalMgr* signalMgr)
{
	do {
		
		// Get a reference to the document. 
		InterfacePtr<IDocumentSignalData> documentSignalData(signalMgr, UseDefaultIID());
		ASSERT(documentSignalData != nil);
		if (documentSignalData == nil) {
			break;
		}
		UIDRef documentUIDRef = documentSignalData->GetDocument();
		
		// Get the service ID from the signal manager
		ServiceID serviceID = signalMgr->GetServiceID();

		// Take action based on the service ID
		switch (serviceID.Get()) 
		{
		
			case kAfterOpenDocSignalResponderService: 
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoAttach();
		//		}
//				InterfacePtr<IObserver> doclnkObserver(documentUIDRef, IID_ILNKWTCHCACHEMANAGER);
//				if (doclnkObserver != nil) {
//					doclnkObserver->AutoAttach();
//				}
				cout << "+++++++++++++++++++++++++ AFTER OPEN DOC EVENT +++++++++++++++++++++++++++" << endl;
				this->AfterOpenDocSignalResponder(documentUIDRef);
				break;
			}
			case kBeforeCloseDocSignalResponderService:
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoDetach();
		//		}
				cout << "+++++++++++++++++++++++++ BEFORE CLOSE DOC EVENT +++++++++++++++++++++++++" << endl;
				//this->BeforeCloseDocSignalResponder(documentUIDRef);
				break;
			}
			case kAfterCloseDocSignalResponderService:
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoDetach();
		//		}
				cout << "+++++++++++++++++++++++++ AFTER CLOSE DOC EVENT ++++++++++++++++++++++++++" << endl;
				//this->AfterCloseDocSignalResponder(documentUIDRef);
				break;
			}
			case kBeforeSaveDocSignalResponderService:
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoDetach();
		//		}
				cout << "+++++++++++++++++++++++++ BEFORE SAVE DOC EVENT ++++++++++++++++++++++++++" << endl;
				this->BeforeSaveDocSignalResponder(documentUIDRef);
				break;
			}
			case kBeforeSaveAsDocSignalResponderService:
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoDetach();
		//		}
				cout << "+++++++++++++++++++++++++ BEFORE SAVE AS DOC EVENT +++++++++++++++++++++++" << endl;
				this->BeforeSaveAsDocSignalResponder(documentUIDRef);
				break;
			}
			case kAfterSaveAsDocSignalResponderService:
			{
		//		InterfacePtr<IObserver> docObserver(documentUIDRef, IID_AMPWTCHRESPONDER);
		//		if (docObserver != nil) {
		//			docObserver->AutoDetach();
		//		}
				cout << "+++++++++++++++++++++++++ AFTER SAVE AS DOC EVENT ++++++++++++++++++++++++" << endl;
				this->AfterSaveAsDocSignalResponder(documentUIDRef);
				break;
			}
		default:
			break;
		}
	} while(false);
}

/********************************************************************************************************************
 *****Function: AfterOpenDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process after open document
 ********************************************************************************************************************/
void LnkWtchDocResponder::AfterOpenDocSignalResponder(UIDRef doc) {
	AMPUtils::GetIDFromTextFrame(doc);
	if (g_CanCheckIn == FALSE)
		return;
	
	AMPUtils::RefreshMainPanel(kAMPLuginCheckoutActionID);
	SaveLogHeaderFile();
}

/********************************************************************************************************************
 *****Function: BeforeCloseDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process before close document
 ********************************************************************************************************************/
void LnkWtchDocResponder::BeforeCloseDocSignalResponder(UIDRef doc){
	if (g_CanCheckIn == FALSE)
		return;
	
	//if (AMPUtils::IsCheckedOutDoc(doc) == FALSE)
	//	return;
	if (g_DocName == "" || g_DocName.compare(AMPUtils::FrontDocName(doc)) != 0){
		cout << "break before check in" << endl;
		return;
	}
	
	// CHECK SESSION IS WORKING
	int update = HTTPRequestHelper::RequestSession();;
	if(update == -1)
	{
		//AMPUtils::UnlockStories();
		//AMPUtils::UnlockPackage();
		// clean up
		cout << "clean up" << endl;
		AMPUtils::ClearAllFile();
		AMPUtils::ClearPackageAndSessionInfo();
		AMPUtils::RefreshMainPanel(FALSE);
		return;
	}
	
	int16 result = AMPCAlert::ModalAlert
	(
	 PMString("\n\nCheck-in your changes?"),		// Alert string
	 PMString("Check-in"),			// OK button
	 PMString("Discard"), 			// No button
	 PMString("Cancel"),			//kNullString, 					// No third button
	 kNeedToWaitForDialog,								// Set OK button to default
	 1								// No icon.
	 );
	if (result == kOKSystem)
	{
		//printf("OK selected - g_DocName : %s \n", g_DocName.c_str());
		
		// check in locked text frames
		//bool storiesCheckinSuccess = FALSE;
		bool idmlCheckinSuccess = FALSE;
		//storiesCheckinSuccess = AMPUtils::CheckInAllStories();
		
		// check in idml file
		bool shouldPost = TRUE;
		cout << "storiesCheckinSuccess event" << endl;
		//shouldPost = FALSE;
		if (shouldPost == TRUE) {
			cout << "DocumentControl event" << endl;
			//idmlCheckinSuccess = AMPDocument::DocumentControl(doc, FALSE);
			idmlCheckinSuccess = AMPDocument::CheckinDocument(doc, FALSE);
		}
		else {
			//isSuccessful = FALSE;
		}
		cout << "idmlCheckinSuccess: " << idmlCheckinSuccess << endl;
		if (idmlCheckinSuccess == TRUE/* && storiesCheckinSuccess == TRUE*/) {
			// clean up
			AMPUtils::ClearAllFile();
			AMPUtils::ClearPackageAndSessionInfo();
			AMPUtils::RefreshMainPanel(FALSE);
			AMPCAlert::ModalAlert
			(
			 "\n\nCheck-in Successful",		// Alert string
			 "OK",							// Yes button
			 kNullString, 					// No button
			 kNullString, 					// No third button
			 kNoNeedToWaitForDialog,		// Set OK button to default
			 1								// No icon.
			 );
			
		} 
		else {
			// display error
			int16 reopenDoc = AMPCAlert::ModalAlert
			(
			 "\n\nFailed to Check-in. Reopen document?",	// Alert string
			 PMString("Yes"), 				// Yes button
			 PMString("No"), 				// No button
			 kNullString, 					// No third button
			 kNeedToWaitForDialog,			// Set kNeedToWaitForDialog to default
			 1								// No icon.
			 );
			if (reopenDoc == 1) {
				DocWatchResponseCode = FALSE;
				// reopen the document
				string tmpPath = g_System_WorkspaceDir;
				string fileIDML = g_Package_id + ".idml";
				string excutePath = "open ";
				excutePath += tmpPath;
				excutePath += "/" + fileIDML;
				system(excutePath.c_str());
			}
			else {
				// do nothing
			}
		}
	}
	else if (result == 2)
	{
		//printf("cancel selected. Should unlock package and stories \n");				
		
		// unlock package and stories
		bool res = FALSE;
		res = AMPUtils::UnlockStories();
		if (res == FALSE) {
			// add to action queue
		}
		res = AMPUtils::UnlockPackage();
		if (res == FALSE) {
			// add to action queue
		}
		else {
			// Clean up
			AMPUtils::ClearAllFile();
			AMPUtils::ClearPackageAndSessionInfo();
			AMPUtils::RefreshMainPanel(FALSE);
		}
	} else {
		return;
	}
	
	// Reset variables
	//AMPUtils::ResetDocName(doc);
	AMPUtils::RefreshMainPanel(FALSE);
	
}

/********************************************************************************************************************
 *****Function: AfterCloseDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process after close document
 ********************************************************************************************************************/
void LnkWtchDocResponder::AfterCloseDocSignalResponder(UIDRef doc){
	
	if(DocWatchResponseCode == TRUE) {
		if(g_DocName != "") {
			bool res = AMPUtils::FindFrontDocsName(g_DocName.c_str());
			if(res == FALSE) {
				AMPUtils::RefreshMainPanel(FALSE);
				AMPUtils::ClearPackageAndSessionInfo();
			}
		}else if(g_DocName == "") {
			AMPUtils::RefreshMainPanel(FALSE);
			AMPUtils::ClearPackageAndSessionInfo();
		}
		SaveLogHeaderFile();
	}
	DocWatchResponseCode = TRUE;
}

/********************************************************************************************************************
 *****Function: BeforeSaveDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process before save document
 ********************************************************************************************************************/
void LnkWtchDocResponder::BeforeSaveDocSignalResponder(UIDRef doc){
	AMPUtils::StoryInfoHiddenSetting();
}

//void LnkWtchDocResponder::AfterSaveDocSignalResponder(UIDRef doc){
//}

/********************************************************************************************************************
 *****Function: BeforeSaveAsDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process before save as document
 ********************************************************************************************************************/
void LnkWtchDocResponder::BeforeSaveAsDocSignalResponder(UIDRef doc){
	if (g_DocName.compare(AMPUtils::FrontDocName()) != 0){
		cout << "--break Command + S" << endl;
		return;
	}
	AMPUtils::StoryInfoHiddenSetting();
}

/********************************************************************************************************************
 *****Function: AfterSaveAsDocSignalResponder
 *****Creator:  Toan Nguyen
 *****IN: UIDRef doc
 *****out: 
 *****Objective: process after save as document
 ********************************************************************************************************************/
void LnkWtchDocResponder::AfterSaveAsDocSignalResponder(UIDRef doc){
	string FrontName = AMPUtils::FrontDocName();
	if(FrontName.find(g_DocName) != string::npos)
	{
		// reset name
		AMPUtils::SetNameDocument(g_DocName);
	}
}
// End, LnkWtchDocResponder.cpp.


